namespace System.Web.Core
{
    public abstract class BaseRequestBinder
    {
        private BaseRequest request;
        private BaseReply reply;

        public BaseRequestBinder(BaseRequest request)
        {
            this.request = request;
        }

        public BaseRequest Request
        {
            get
            {
                return request;
            }
        }
        public BaseReply Reply
        {
            get
            {
                return reply;
            }
            internal set
            {
                reply = value;
            }
        }

        public virtual BaseReply ExecuteRequest()
        {
            return null;
        }
        public virtual void AsynchronousSendRequest()
        {
        }
        public virtual void SendRequest()
        {
        }
        public virtual void ConvertReply()
        {
        }
    }
    public abstract class RequestBinder : BaseRequestBinder
    {
        private IReplyConverter converter;

        public RequestBinder(IReplyConverter converter, BaseRequest request)
            : base(request)
        {
            this.converter = converter;
        }

        public IReplyConverter Converter
        {
            get
            {
                return converter;
            }
        }
    }

    public class TBaseRequestBinder<TReply, TOperation> : BaseRequestBinder
        where TReply : BaseReply, new()
        where TOperation : BaseOperation
    {
        public TBaseRequestBinder(BaseRequest request)
            : base(request)
        {
            Reply = new TReply() as BaseReply;
        }

        public override BaseReply ExecuteRequest()
        {
            return Request.Send(this);
        }
    }
    public class TRequestBinder<TReply, TOperation> : RequestBinder
        where TReply : BaseReply, new()
        where TOperation : BaseOperation
    {
        public TRequestBinder(IReplyConverter converter, BaseRequest request)
            : base(converter, request)
        {
            Reply = new TReply() as BaseReply;
        }

        public override void SendRequest()
        {
            Request.Send(this);
            ConvertReply();
        }
        public override void AsynchronousSendRequest()
        {
            //TODO, not support Asynchronous sending request now.
        }
        public override void ConvertReply()
        {
            ((IReplyConverter<TReply, TOperation>)Converter).ConvertReply((TReply)Reply, null);
        }
    }
}